/********************************************************************************
* @author: Liu  HZ
* @date: 2024/5/25
* @description: 
********************************************************************************/

#include <iostream>
#include <memory>
#include <cstring>

using namespace std;

//1. 值传递
void mySwap01(int a, int b) {
    int temp = a;
    a = b;
    b = temp;
}

//2. 地址传递
void mySwap02(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

//3. 引用传递
void mySwap03(int &a, int &b) {
    int temp = a;
    a = b;
    b = temp;
}

class Person {
public:
    Person() {
        cout << "无参构造函数!" << endl;
        mAge = 0;
    }

    Person(int age) {
        cout << "有参构造函数!" << endl;
        mAge = age;
    }

    Person(const Person &p) {
        cout << "拷贝构造函数!" << endl;
        mAge = p.mAge;
    }

    //析构函数在释放内存之前调用
    ~Person() {
        cout << "析构函数!" << endl;
    }

public:
    int mAge;
};

//1. 使用一个已经创建完毕的对象来初始化一个新对象
void test01() {

    Person man(100);      //p对象已经创建完毕
    Person newman(man);   //调用拷贝构造函数
    Person newman2 = man; //拷贝构造

    //Person newman3;
    //newman3 = man; //不是调用拷贝构造函数,赋值操作
}

//2. 值传递的方式给函数参数传值
//相当于Person p1 = p;
void doWork(Person p1) {}

void test02() {
    Person p;    //无参构造函数
    doWork(p);
}

//3. 以值方式返回局部对象
Person doWork2() {
    Person p1;
    cout << (int *) &p1 << endl;
    return p1;
}

void test03() {
    Person p = doWork2();
    cout << (int *) &p << endl;
    cout << p.mAge << endl;
}

struct Person1 {
    int age;
    char name[50];
};

union Address {
    char street[100];
    char city[50];
};

int main() {
//    int a = 10;
//    int b = 20;
//    //int &c;   //错误，引用必须初始化
//    int &c = a; //一旦初始化后,就不可以更改
//    c = b;      //这是赋值操作,不是更改引用
//
//    cout << "a = " << a << endl;
//    cout << "b = " << b << endl;
//    cout << "c = " << c << endl;


//    int a = 10, b = 20;

//    mySwap01(a, b);
//    cout << "a:" << a << " b:" << b << endl;
//
//    mySwap02(&a, &b);
//    cout << "a:" << a << " b:" << b << endl;
//
//    mySwap03(a, b);
//    cout << "a:" << a << " b:" << b << endl;


//    test03();

//    int *ptr;              // 未初始化的指针
//    int &ref = *ptr;       // 错误：引用必须初始化
//    // 由于未定义行为(Undefined Behavior, UB),ptr具有随机性,ref可能会有值
//    cout << ref << endl;

//    int a = 10, b = 20;
//
//    int &ref = a;     // 声明引用并初始化为 a
//    std::cout << "a: " << a << ", ref: " << ref << std::endl;
//
//    ref = 30;         // 更改引用所引用的对象的值
//    std::cout << "After changing ref, a: " << a << ", ref: " << ref << std::endl;
//
//    // 不是在改变引用 ref 所指向的对象,而是在将 b 的值赋给 ref 所指向的对象 a.
//    // 这是因为 ref 是 a 的别名, 所以对 ref 的赋值操作就像是直接对 a 进行赋值操作
//    ref = b;
//    std::cout << "After changing ref, a: " << a << ", ref: " << ref << std::endl;
//
//    // 尝试更改引用所引用的对象（这将导致编译错误）
//    // ref = &b; // 错误：不能给引用赋值新的地址

//    int var = 42;
//    int *ptr = &var;
//    int &ref = var;
//
//    std::cout << "Address of var: " << &var << std::endl;     // var 变量的地址
//    std::cout << "Value of ptr: " << ptr << std::endl;        // 指针 ptr 的值, 即 var 变量的地址
//    std::cout << "Value via pointer: " << *ptr << std::endl;  // 解引用指针, 得到 var 的值
//    std::cout << "Address of ref: " << &ref << std::endl;     // 引用 ref 的地址, 与 var 的地址相同, 因为 ref 是 var 的别名
//    // 引用 ref 的值, 即 var 的值. 由于 ref 是 var 的别名, 所以它的值与 var 的值相同
//    std::cout << "Address of ref: " << ref << std::endl;


//    int var1 = 42;
//    int var2 = 100;
//    int *ptr = &var1;
//    int &ref = var1;
//
//    ptr = &var2; // 重新赋值指针
//    ref = var2;  // 错误：不能重新赋值引用
//
//    std::cout << "Pointer now points to: " << *ptr << std::endl;
//    std::cout << "Reference still refers to: " << ref << std::endl;


//    int var = 42;
//    int *ptr = &var;
//    int **ptr_to_ptr = &ptr;
//
//    std::cout << "Value via double pointer: " << **ptr_to_ptr << std::endl;
//    std::cout << "Value via double pointer: " << *ptr_to_ptr << std::endl;
//    std::cout << "Value via double pointer: " << &ptr << std::endl;



//    int *dynamicVar = new int(42); // 动态分配内存
//    int &ref = *dynamicVar;        // 引用动态分配的内存
//
//    std::cout << "Dynamically allocated value: " << *dynamicVar << std::endl;
//    std::cout << "Value via reference: " << ref << std::endl;
//
//    delete dynamicVar; // 释放内存


    Person1 p{25, "John Doe"};
    // 结构体成员可以同时被访问
    std::cout << "Person: " << p.age << ", " << p.name << std::endl;

    Address a{};
    strcpy(a.street, "123 Main St");
    // 联合体成员一次只能访问一个: 此时往共享内存中写入的是 street
    std::cout << "Union: " << a.street << ", " << a.city << std::endl;
    // 输出: Union: 123 Main St, 123 Main St

    strcpy(a.city, "AnyTown");
    // 此时往共享内存中写入的是 city
    std::cout << "Union: " << a.street << ", " << a.city << std::endl;
    // 输出: Union: AnyTown, AnyTown
}
